package com.fancy.music.controller;

import com.fancy.common.dto.response.Result;
import com.fancy.music.config.FileUploadConfig;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;

@Api(tags = "文件服务")
@RestController
@RequestMapping("/api/v1/files")
@RequiredArgsConstructor
@Slf4j
public class FileController {

    private final FileUploadConfig fileUploadConfig;

    @ApiOperation(value = "获取音频文件", notes = "根据文件路径获取音频文件")
    @ApiImplicitParam(name = "filename", value = "文件名", required = true, paramType = "path", dataType = "string")
    @GetMapping("/audio/{filename}")
    public ResponseEntity<Resource> getAudioFile(@PathVariable String filename) {
        return getFile(fileUploadConfig.getAudioPath() + filename, "audio");
    }

    @ApiOperation(value = "获取封面图片", notes = "根据文件路径获取封面图片")
    @ApiImplicitParam(name = "filename", value = "文件名", required = true, paramType = "path", dataType = "string")
    @GetMapping("/covers/{filename}")
    public ResponseEntity<Resource> getCoverFile(@PathVariable String filename) {
        return getFile(fileUploadConfig.getCoverPath() + filename, "image");
    }

    @ApiOperation(value = "获取歌词文件", notes = "根据文件路径获取歌词文件")
    @ApiImplicitParam(name = "filename", value = "文件名", required = true, paramType = "path", dataType = "string")
    @GetMapping("/lyrics/{filename}")
    public ResponseEntity<Resource> getLyricFile(@PathVariable String filename) {
        return getFile(fileUploadConfig.getLyricPath() + filename, "text");
    }

    @ApiOperation(value = "下载文件", notes = "下载指定的文件")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "type", value = "文件类型(audio/cover/lyric)", required = true, paramType = "path", dataType = "string"),
        @ApiImplicitParam(name = "filename", value = "文件名", required = true, paramType = "path", dataType = "string")
    })
    @GetMapping("/download/{type}/{filename}")
    public ResponseEntity<Resource> downloadFile(@PathVariable String type, @PathVariable String filename) {
        String subPath;
        switch (type.toLowerCase()) {
            case "audio":
                subPath = fileUploadConfig.getAudioPath();
                break;
            case "cover":
                subPath = fileUploadConfig.getCoverPath();
                break;
            case "lyric":
                subPath = fileUploadConfig.getLyricPath();
                break;
            default:
                return ResponseEntity.badRequest().build();
        }

        Path filePath = Paths.get(fileUploadConfig.getBasePath() + subPath + filename);
        File file = filePath.toFile();

        if (!file.exists() || !file.isFile()) {
            return ResponseEntity.notFound().build();
        }

        Resource resource = new FileSystemResource(file);

        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"")
                .contentLength(file.length())
                .body(resource);
    }

    @ApiOperation(value = "获取文件信息", notes = "获取文件的基本信息")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "type", value = "文件类型(audio/cover/lyric)", required = true, paramType = "path", dataType = "string"),
        @ApiImplicitParam(name = "filename", value = "文件名", required = true, paramType = "path", dataType = "string")
    })
    @GetMapping("/info/{type}/{filename}")
    public Result<FileInfo> getFileInfo(@PathVariable String type, @PathVariable String filename) {
        String subPath;
        switch (type.toLowerCase()) {
            case "audio":
                subPath = fileUploadConfig.getAudioPath();
                break;
            case "cover":
                subPath = fileUploadConfig.getCoverPath();
                break;
            case "lyric":
                subPath = fileUploadConfig.getLyricPath();
                break;
            default:
                return Result.fail("不支持的文件类型");
        }

        Path filePath = Paths.get(fileUploadConfig.getBasePath() + subPath + filename);
        File file = filePath.toFile();

        if (!file.exists() || !file.isFile()) {
            return Result.fail("文件不存在");
        }

        FileInfo fileInfo = new FileInfo();
        fileInfo.setFilename(filename);
        fileInfo.setSize(file.length());
        fileInfo.setLastModified(file.lastModified());
        fileInfo.setPath(subPath + filename);

        return Result.success(fileInfo);
    }

    private ResponseEntity<Resource> getFile(String relativePath, String contentType) {
        try {
            Path filePath = Paths.get(fileUploadConfig.getBasePath() + relativePath);
            File file = filePath.toFile();

            if (!file.exists() || !file.isFile()) {
                return ResponseEntity.notFound().build();
            }

            Resource resource = new FileSystemResource(file);

            MediaType mediaType;
            switch (contentType) {
                case "audio":
                    mediaType = MediaType.parseMediaType("audio/mpeg");
                    break;
                case "image":
                    mediaType = MediaType.IMAGE_JPEG;
                    break;
                case "text":
                    mediaType = MediaType.TEXT_PLAIN;
                    break;
                default:
                    mediaType = MediaType.APPLICATION_OCTET_STREAM;
            }

            return ResponseEntity.ok()
                    .contentType(mediaType)
                    .contentLength(file.length())
                    .header(HttpHeaders.CACHE_CONTROL, "max-age=3600")
                    .body(resource);

        } catch (Exception e) {
            log.error("获取文件失败: {}", relativePath, e);
            return ResponseEntity.internalServerError().build();
        }
    }

    @ApiModel("文件信息")
    public static class FileInfo {
        @ApiModelProperty("文件名")
        private String filename;

        @ApiModelProperty("文件大小（字节）")
        private Long size;

        @ApiModelProperty("最后修改时间")
        private Long lastModified;

        @ApiModelProperty("文件路径")
        private String path;

        // Getters and Setters
        public String getFilename() { return filename; }
        public void setFilename(String filename) { this.filename = filename; }

        public Long getSize() { return size; }
        public void setSize(Long size) { this.size = size; }

        public Long getLastModified() { return lastModified; }
        public void setLastModified(Long lastModified) { this.lastModified = lastModified; }

        public String getPath() { return path; }
        public void setPath(String path) { this.path = path; }
    }
}
